import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import akka.actor.ActorRef;
import akka.actor.UntypedActor;

/**
 * Using a regex pattern, scans a file for matches.
 * 
 * Sends results to a CollectionActor. Is configured by Configure.
 */
public class ScanActor extends UntypedActor {
	private String fileToScan;
	private ActorRef collectionActor;
	private Pattern pattern;
	
	@Override
	public void onReceive(Object message) {
		if (message instanceof Configure) {
			Configure conf = (Configure)message;
			this.fileToScan = conf.getName();
			this.collectionActor = conf.getCollectionActor();
			this.pattern = conf.getPattern();
		} else {
			throw new IllegalArgumentException("Unknown message: " + message);
		}
		try {
			scan();
		} catch (FileNotFoundException e) {
			List<String> msg = Arrays.asList("FILE NOT FOUND!");
			collectionActor.tell(new Found(fileToScan, msg));
		} catch (IOException e) {
			List<String> msg = Arrays.asList("ERROR READING FILE!");
			collectionActor.tell(new Found(fileToScan, msg));
		}
	}
	
	/**
	 * Scans configured file and tells CollectionActor of any matches
	 * @throws FileNotFoundException when passed filename does not exist
	 * @throws IOException when error reading lines from file
	 */
	private void scan() throws FileNotFoundException, IOException {
		BufferedReader bufRead;
		List<String> foundList = new ArrayList<String>();
		
		if (fileToScan == "-") {
			// No filename provided - take input from stdin
			bufRead = new BufferedReader(new InputStreamReader(System.in));	
		} else {
			bufRead = new BufferedReader(new FileReader(fileToScan));				
		}

		String line = bufRead.readLine();
		int count = 0;
		while (line != null){
			count++;
			if(pattern.matcher(line).find()) {
				String matchString = count + " " + line;
				foundList.add(matchString);
			}
			line = bufRead.readLine();
		}
		collectionActor.tell(new Found(fileToScan, foundList));
	}
}